/**
 * <copyright>
 * Copyrigth 2007 Aurelien Moreau
 *
 * This file is part of ProcessShop.
 *
 * ProcessShop is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * ProcessShop is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with ProcessShop; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * </copyright>
 *
 * $Id$
 */
package net.yienyien.process.bpel.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.yienyien.process.bpel.generator.controlFlow.ControlFlowContrib;
import net.yienyien.process.bpel.generator.dataFlow.DataFlowContrib;
import net.yienyien.process.bpel.generator.impl.ProductionImpl;
import net.yienyien.process.bpel.generator.init.InitContrib;
import net.yienyien.process.bpel.generator.partner.PartnerContrib;
import net.yienyien.process.folder.BPDFolder;
import net.yienyien.process.folder.BPDFolderFactory;

import org.eclipse.emf.ecore.EObject;

public class BPELGenerator implements BPELGeneratorListener{
	
	private BPDFolder folder;
	private ArrayList<Contrib> contribs=new ArrayList<Contrib>();
	private ArrayList<BPELGeneratorListener> listeners=new ArrayList<BPELGeneratorListener>();
	
	public BPELGenerator() {
		folder = BPDFolderFactory.INSTANCE.newBPDFolder();
		addContrib(new InitContrib());
		addContrib(new PartnerContrib());
		addContrib(new DataFlowContrib());
		addContrib(new ControlFlowContrib());
	}
	
	public BPDFolder getFolder() {
		return folder;
	}
	
	public void addContrib(Contrib contrib) {
		contribs.add(contrib);
		contrib.setGenerator(this);
	}
	
	public List<Contrib> getContribs() {
		return contribs;
	}
	
	public void addListener(BPELGeneratorListener listener) {
		listeners.add(listener);
	}
	
	public List<BPELGeneratorListener> getListeners() {
		return listeners;
	}
	
	public Production generate(Map<String, EObject> contribution) throws BPELGenerationException {
		ProductionImpl production=new ProductionImpl();
		
		for(Contrib contrib: contribs) {
			EObject contribData=contribution.get(contrib.getContribKey());
			prepare(contrib);
			contrib.prepare(production, contribData);
		}
		
		for(Contrib contrib: contribs) {
			start(contrib);
			contrib.contrib();
			end(contrib);
		}
		
		return production;
	}

	@Override
	public void prepare(Contrib contrib) {
		for(BPELGeneratorListener l: listeners) {
			l.prepare(contrib);
		}
	}
	
	@Override
	public void end(Contrib contrib) {
		for(BPELGeneratorListener l: listeners) {
			l.end(contrib);
		}
	}

	@Override
	public void start(Contrib contrib) {
		for(BPELGeneratorListener l: listeners) {
			l.start(contrib);
		}
	}
	
}
